package com.shujia.jichu

/**
 * 面向对象编程思想：是将对象传来传去的
 * 1、将对象作为方法的参数进行传递
 * 2、将对象作为方法的返回值类型进行返回
 * 需要明确的是对象的类，抽象类或者接口的类型，可以使用多态进行传递或者返回
 *
 * 函数式编程思想：将函数传来传去
 * 1、将函数A作为函数B的参数进行传递  必须要熟练掌握的
 * 2、将函数A作为函数B的返回值类型    必须要能够看懂即可
 * 需要明确的是函数的类型 -- 主要是由参数列表和返回值类型决定的
 * 使用scala语法描述一个函数类型：
 * 举例：String => Int
 */
object Demo10Fun {
  def main(args: Array[String]): Unit = {

    /**
     * strToInt是一个参数是String类型，返回值是Int类型的函数
     */
    def strToInt(str: String): Int = {
      //scala字符串中的方法
      str.toInt
    }

    val n1: Int = strToInt("1000")
    println(n1)

    //    Student s1 = new Student()
    //    Student s2 = s1

    //万物皆对象，函数也是一个对象
    val strToIntTemp: String => Int = strToInt
    val n2: Int = strToIntTemp("200")
    println(n2)

    println("=" * 100)

    /**
     * 函数作为参数进行传递
     *
     * 作用：本质上就是将函数的主体逻辑抽取出来，当作参数传递给函数
     */
    //定义一个参数是函数的函数

    /**
     * 定义了一个fun函数，函数的参数是一个参数为String类型返回值是Int类型的函数
     */
    def fun(s: String, f: String => Int): Unit = {
      val res: Int = f(s)
      println("执行2")
      println(res)
    }

    def method1(s: String): Int = {
      println("执行1")
      s.toInt + 1000
    }

    def method2(s: String): Int = {
      s.toInt + 9999
    }

    //调用一下fun函数
    //这里需要传一个参数是String类型返回值是Int类型的函数
    fun("1000", method1)
    //fun函数中的函数参数，可以是不同的实现逻辑，只要传入的函数符合参数是一个参数为String类型返回值是Int类型即可
    fun("2000", method2)

    /**
     * 函数作为方法参数传递的时候，这里的参数函数可以使用lambda表达式改写
     * lambda表达式 -- 匿名函数 （没有名字的函数）
     * (s:String) => s.toInt
     *
     */
    val f1: String => Int = (s: String) => s.toInt + 22
    fun("11", f1)

    //函数只有一行的时候，传参可以直接传入一个匿名函数
    fun("22", (s: String) => s.toInt + 100)

    //lambda表达式的参数类型可以进行自动推断
    fun("22", s => s.toInt)

    //如果传入的函数参数有且仅只用了一次的话，可以直接使用_代替
    fun("22", _.toInt)


  }
}
